package com.tao.content.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.tao.base.exception.LearnHubException;
import com.tao.content.domain.dto.SaveOrUpdateTeachPlanDto;
import com.tao.content.domain.dto.TeachPlanDetailDto;
import com.tao.content.domain.pojo.Teachplan;
import com.tao.content.domain.pojo.TeachplanMedia;
import com.tao.content.mapper.TeachplanMapper;
import com.tao.content.service.ITeachplanService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.xml.stream.events.DTD;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 课程计划 服务实现类
 * </p>
 *
 * @author taohongrun
 * @since 2024-11-01
 */
@Service
@Slf4j
public class TeachplanServiceImpl extends ServiceImpl<TeachplanMapper, Teachplan> implements ITeachplanService {

    @Override
    public List<TeachPlanDetailDto> queryTeachPlan(){
        List<TeachPlanDetailDto> allList = lambdaQuery()
                .orderByAsc(Teachplan::getOrderby)
                .list()
                .stream()
                .map(m -> {
                    TeachPlanDetailDto teachPlanDetailDto = new TeachPlanDetailDto();
                    BeanUtils.copyProperties(m, teachPlanDetailDto);
                    setMedia(teachPlanDetailDto);
                    return teachPlanDetailDto;
                })
                .toList();
        log.info("所有教学计划信息为:{}",allList);
        List<TeachPlanDetailDto> firstNodes = allList.stream()
                .filter(f -> f.getParentid().equals(0L))
                .toList();
        log.info("所有教学计划信息为:{}",firstNodes);
        List<TeachPlanDetailDto> childrenNodes = allList.stream()
                .filter(f -> !f.getParentid().equals(0L))
                .toList();
        log.info("所有教学计划信息为:{}",childrenNodes);
        for (TeachPlanDetailDto p: firstNodes
             ) {
            setChildrenNodes(p,childrenNodes);
        }

        return firstNodes;
    }

    @Override
    public void setMedia(TeachPlanDetailDto teachPlanDetailDto){
        List<TeachplanMedia> teachplanMediaList = Db.lambdaQuery(TeachplanMedia.class)
                .eq(TeachplanMedia::getTeachplanId, teachPlanDetailDto.getId())
                .list();
        teachPlanDetailDto.setMediaList(teachplanMediaList);
        log.info("id为:{}的teachPlan相关媒体信息为:{}",teachPlanDetailDto.getId(),teachplanMediaList);
    }


    private void setChildrenNodes(TeachPlanDetailDto parent,List<TeachPlanDetailDto> childrenNodes){
        List<TeachPlanDetailDto> parentChildren = childrenNodes.stream()
                .filter(f -> f.getParentid().equals(parent.getId()))
                .toList();
        if(parentChildren.isEmpty()) return;
        parent.setChildrenNodes(parentChildren);
        parent.getChildrenNodes().forEach(f -> setChildrenNodes(f,childrenNodes));
    }

    @Override
    public void saveOrUpdateTeachPlan(SaveOrUpdateTeachPlanDto saveOrUpdateTeachPlanDto){
        //异常处理
        //以三种异常情况为例
        if(saveOrUpdateTeachPlanDto.getGrade()!=1 && saveOrUpdateTeachPlanDto.getParentid()==0)
            LearnHubException.throwMyException("输入信息有误，一级节点父id必须为0");
        if(saveOrUpdateTeachPlanDto.getGrade() != 1 && saveOrUpdateTeachPlanDto.getGrade() != 2)
            LearnHubException.throwMyException("输入信息有误，仅有两级节点");
        if(lambdaQuery().eq(Teachplan::getId, saveOrUpdateTeachPlanDto.getParentid()).list().isEmpty() && saveOrUpdateTeachPlanDto.getParentid()!=0)
            LearnHubException.throwMyException("输入信息有误，父节点不存在");
        //id存在则为修改，不存在则为新增
        Long id = saveOrUpdateTeachPlanDto.getId();

        if (id==null){
            Teachplan teachplan = new Teachplan();
            BeanUtils.copyProperties(saveOrUpdateTeachPlanDto,teachplan);
            //含orderBy的新增，需要赋值orderBy,赋值为参与排序的orderBy最大值+1
            //由于大章节与小章节参与排序的顺序不一样，需要单独寻找参与排序的orderBy
            Integer orderBy = lambdaQuery()
                    .select(Teachplan::getOrderby)
                    .eq(Teachplan::getParentid, saveOrUpdateTeachPlanDto.getParentid())
                    .list()
                    .stream()
                    .map(Teachplan::getOrderby)
                    .max(Integer::compareTo)
                    .orElse(0);//若数组为null，则排第一位
            teachplan.setOrderby(orderBy+1);

            teachplan.setStatus(1);

            save(teachplan);
        }else {
            //查询回显后修改，可以保证原先的数据不会被null覆盖，可以直接根据id修改
            //直接修改，必须要用，条件修改，因为前端不一定传什么值，防止被覆盖
            lambdaUpdate()
                    .set(!saveOrUpdateTeachPlanDto.getPname().isEmpty(),Teachplan::getPname,saveOrUpdateTeachPlanDto.getPname())
                    .set(saveOrUpdateTeachPlanDto.getGrade()!=null,Teachplan::getGrade,saveOrUpdateTeachPlanDto.getGrade())
                    .set(saveOrUpdateTeachPlanDto.getParentid()!=null,Teachplan::getParentid,saveOrUpdateTeachPlanDto.getParentid())
                    .eq(Teachplan::getId,saveOrUpdateTeachPlanDto.getId())
                    .update();
        }
    }

    @Override
    public void deleteTeachPlan(Long id){
        Teachplan teachplan = getById(id);
        if(teachplan == null) LearnHubException.throwMyException("该教学计划不存在");
        if(teachplan.getGrade()==1){
            List<Teachplan> childList = lambdaQuery().eq(Teachplan::getParentid, id).list();
            if(!childList.isEmpty())
                LearnHubException.throwMyException("课程计划信息还有子级信息，无法操作");
            else {
                removeById(id);
            }
        }else {
            removeById(id);
            //删除关联媒体
            Db.lambdaUpdate(TeachplanMedia.class).eq(TeachplanMedia::getTeachplanId,id).remove();
        }
    }

    @Override
    public void movedownTeachPlan(Long id){
        Teachplan currentTeachplan = getById(id);
        if(currentTeachplan == null) LearnHubException.throwMyException("该教学计划不存在");

        // 查询当前记录的顺序值
        Integer currentOrderBy = currentTeachplan.getOrderby();

        // 查询顺序值比当前记录顺序值大的下一条记录
        Teachplan nextTeachplan = lambdaQuery()
                .eq(Teachplan::getParentid,currentTeachplan.getParentid())//别忽略同一层级
                .gt(Teachplan::getOrderby, currentOrderBy)
                .orderByAsc(Teachplan::getOrderby)
                .last("LIMIT 1")
                .one();

        // 确保有下一条记录可以交换
        if (nextTeachplan != null) {
            // 交换顺序值
            Integer nextOrderBy = nextTeachplan.getOrderby();

            // 更新当前记录的顺序值为下一条记录的顺序值
            currentTeachplan.setOrderby(nextOrderBy);
            updateById(currentTeachplan);

            // 更新下一条记录的顺序值为当前记录的顺序值
            nextTeachplan.setOrderby(currentOrderBy);
            updateById(nextTeachplan);
        } else {
            LearnHubException.throwMyException("已经为最后一个，无法下移");
        }

    }

    @Override
    public void moveupTeachPlan(Long id){
        Teachplan currentTeachplan = getById(id);
        if(currentTeachplan == null) LearnHubException.throwMyException("改教学计划不存在");

        // 查询当前记录的顺序值
        Integer currentOrderBy = currentTeachplan.getOrderby();

        // 在同一层级中查询顺序值比当前记录顺序值大的下一条记录
        Teachplan preTeachplan = lambdaQuery()
                .eq(Teachplan::getParentid,currentTeachplan.getParentid())//别忽略同一层级
                .lt(Teachplan::getOrderby, currentOrderBy)
                .orderByAsc(Teachplan::getOrderby)
                .last("LIMIT 1")
                .one();

        // 确保有下一条记录可以交换
        if (preTeachplan != null) {
            // 交换顺序值
            Integer nextOrderBy = preTeachplan.getOrderby();

            // 更新当前记录的顺序值为下一条记录的顺序值
            currentTeachplan.setOrderby(nextOrderBy);
            updateById(currentTeachplan);

            // 更新下一条记录的顺序值为当前记录的顺序值
            preTeachplan.setOrderby(currentOrderBy);
            updateById(preTeachplan);
        } else {
            LearnHubException.throwMyException("已经为第一个，无法上移");
        }
    }
}
